import { Vec3 } from '@/core/types';
import { BlockType } from '@/blocks/types';
import { WorldManager } from './WorldManager';

/**
 * 树木生成器 - 在世界中生成各种类型的树木
 */
export class TreeGenerator {
  private worldManager: WorldManager;

  constructor(worldManager: WorldManager) {
    this.worldManager = worldManager;
  }

  /**
   * 在指定位置生成一棵树
   */
  public generateTree(position: Vec3, treeType: 'oak' | 'birch' | 'spruce' = 'oak'): boolean {
    // 检查是否有足够的空间生成树
    if (!this.canPlaceTree(position, treeType)) {
      return false;
    }

    switch (treeType) {
      case 'oak':
        this.generateOakTree(position);
        break;
      case 'birch':
        this.generateBirchTree(position);
        break;
      case 'spruce':
        this.generateSpruceTree(position);
        break;
    }

    return true;
  }

  /**
   * 生成橡树
   */
  private generateOakTree(position: Vec3): void {
    const { x, y, z } = position;
    const trunkHeight = 4 + Math.floor(Math.random() * 3); // 4-6格高

    // 生成树干
    for (let i = 0; i < trunkHeight; i++) {
      this.worldManager.setBlock({ x, y: y + i, z }, BlockType.LOG);
    }

    // 生成树叶层
    const leafY = y + trunkHeight - 1;
    
    // 顶层树叶 (3x3)
    for (let dx = -1; dx <= 1; dx++) {
      for (let dz = -1; dz <= 1; dz++) {
        if (Math.random() > 0.1) { // 90%概率生成树叶
          this.worldManager.setBlock({ x: x + dx, y: leafY + 1, z: z + dz }, BlockType.LEAVES);
        }
      }
    }

    // 中层树叶 (5x5)
    for (let dx = -2; dx <= 2; dx++) {
      for (let dz = -2; dz <= 2; dz++) {
        const distance = Math.abs(dx) + Math.abs(dz);
        if (distance <= 2 && Math.random() > 0.05) { // 95%概率生成树叶
          this.worldManager.setBlock({ x: x + dx, y: leafY, z: z + dz }, BlockType.LEAVES);
        }
      }
    }

    // 底层树叶 (5x5，稍微稀疏)
    for (let dx = -2; dx <= 2; dx++) {
      for (let dz = -2; dz <= 2; dz++) {
        const distance = Math.abs(dx) + Math.abs(dz);
        if (distance <= 2 && Math.random() > 0.2) { // 80%概率生成树叶
          this.worldManager.setBlock({ x: x + dx, y: leafY - 1, z: z + dz }, BlockType.LEAVES);
        }
      }
    }
  }

  /**
   * 生成白桦树
   */
  private generateBirchTree(position: Vec3): void {
    const { x, y, z } = position;
    const trunkHeight = 5 + Math.floor(Math.random() * 2); // 5-6格高

    // 生成树干
    for (let i = 0; i < trunkHeight; i++) {
      this.worldManager.setBlock({ x, y: y + i, z }, BlockType.BIRCH_LOG);
    }

    // 生成树叶（白桦树的树叶更加紧凑）
    const leafY = y + trunkHeight - 1;
    
    // 顶层
    this.worldManager.setBlock({ x, y: leafY + 1, z }, BlockType.BIRCH_LEAVES);
    
    // 中层 (3x3)
    for (let dx = -1; dx <= 1; dx++) {
      for (let dz = -1; dz <= 1; dz++) {
        if (Math.random() > 0.1) {
          this.worldManager.setBlock({ x: x + dx, y: leafY, z: z + dz }, BlockType.BIRCH_LEAVES);
        }
      }
    }

    // 底层 (3x3)
    for (let dx = -1; dx <= 1; dx++) {
      for (let dz = -1; dz <= 1; dz++) {
        if (Math.random() > 0.2) {
          this.worldManager.setBlock({ x: x + dx, y: leafY - 1, z: z + dz }, BlockType.BIRCH_LEAVES);
        }
      }
    }
  }

  /**
   * 生成云杉树
   */
  private generateSpruceTree(position: Vec3): void {
    const { x, y, z } = position;
    const trunkHeight = 6 + Math.floor(Math.random() * 3); // 6-8格高

    // 生成树干
    for (let i = 0; i < trunkHeight; i++) {
      this.worldManager.setBlock({ x, y: y + i, z }, BlockType.SPRUCE_LOG);
    }

    // 生成锥形树叶
    const leafY = y + trunkHeight - 1;
    
    // 顶部尖端
    this.worldManager.setBlock({ x, y: leafY + 2, z }, BlockType.SPRUCE_LEAVES);
    
    // 从上到下生成锥形树叶
    for (let layer = 0; layer < 4; layer++) {
      const currentY = leafY + 1 - layer;
      const radius = Math.min(layer + 1, 2);
      
      for (let dx = -radius; dx <= radius; dx++) {
        for (let dz = -radius; dz <= radius; dz++) {
          const distance = Math.abs(dx) + Math.abs(dz);
          if (distance <= radius && Math.random() > 0.1) {
            this.worldManager.setBlock({ x: x + dx, y: currentY, z: z + dz }, BlockType.SPRUCE_LEAVES);
          }
        }
      }
    }
  }

  /**
   * 检查是否可以在指定位置放置树
   */
  private canPlaceTree(position: Vec3, treeType: string): boolean {
    const { x, y, z } = position;
    
    // 检查地面是否为草地或泥土
    const groundBlock = this.worldManager.getBlock({ x, y: y - 1, z });
    if (groundBlock !== BlockType.GRASS && groundBlock !== BlockType.DIRT) {
      return false;
    }

    // 检查树干位置是否为空气
    const maxHeight = treeType === 'spruce' ? 8 : 6;
    for (let i = 0; i < maxHeight + 3; i++) {
      const checkBlock = this.worldManager.getBlock({ x, y: y + i, z });
      if (checkBlock !== BlockType.AIR) {
        return false;
      }
    }

    // 检查周围是否有足够空间
    for (let dx = -3; dx <= 3; dx++) {
      for (let dz = -3; dz <= 3; dz++) {
        for (let dy = 0; dy < 3; dy++) {
          const checkBlock = this.worldManager.getBlock({ x: x + dx, y: y + maxHeight + dy, z: z + dz });
          if (checkBlock !== BlockType.AIR) {
            return false;
          }
        }
      }
    }

    return true;
  }

  /**
   * 在区块中随机生成树木
   */
  public generateTreesInChunk(chunkX: number, chunkZ: number, density: number = 0.02): void {
    const chunkSize = 16;
    const startX = chunkX * chunkSize;
    const startZ = chunkZ * chunkSize;

    for (let x = startX; x < startX + chunkSize; x++) {
      for (let z = startZ; z < startZ + chunkSize; z++) {
        if (Math.random() < density) {
          // 找到地面高度
          let groundY = -1;
          for (let y = 60; y >= 0; y--) {
            const block = this.worldManager.getBlock({ x, y, z });
            if (block === BlockType.GRASS || block === BlockType.DIRT) {
              groundY = y + 1;
              break;
            }
          }

          if (groundY > 0) {
            // 随机选择树的类型
            const treeTypes: ('oak' | 'birch' | 'spruce')[] = ['oak', 'birch', 'spruce'];
            const treeType = treeTypes[Math.floor(Math.random() * treeTypes.length)];
            
            this.generateTree({ x, y: groundY, z }, treeType);
          }
        }
      }
    }
  }
}